<?php
require_once dirname(__FILE__) . '/bootstrap.php';
require_once 'PHPUnit/TextUI/TestRunner.php';

class TestSuiteHelper
{
  private $name;
  private $suite;

  private function __construct($name)
  {
    $this->name  = $name;
    $this->suite = new PHPUnit_Framework_TestSuite($name);
  }

  public static function create($name, $path)
  {
    $suite = new self($name);
    $suite->setMainMethod();
    $suite->requireTests($path);
    return $suite;
  }

  public function suite()
  {
    return $this->suite;
  }

  public function run()
  {
    if (PHPUnit_MAIN_METHOD == $this->name) {
      $arguments = array();
      foreach ($_SERVER['argv'] as $arg) {
        if ($arg == '--report') {
          $arguments = array(
            'reportDirectory' => realpath(dirname(__FILE__) . '/reports'),
            'testdoxHTMLFile' => dirname(__FILE__) . '/../docs/testdox.html'
          );
        }
      }
      PHPUnit_Util_Filter::addDirectoryToFilter(dirname(__FILE__));
      PHPUnit_TextUI_TestRunner::run($this->suite, $arguments);
    }
  }

  private function setMainMethod()
  {
    if (!defined('PHPUnit_MAIN_METHOD')) {
      define('PHPUnit_MAIN_METHOD', $this->name);
    }
  }

  private function requireTests($path)
  {
    // require all tests from $path and all suites from sub-directories
    $path = realpath($path);
    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
    foreach ($it as $fileInfo) {
      if (!$fileInfo->isFile()) continue;

      if (preg_match('/^(\w*Tests?).php$/', $fileInfo->getFilename(), $matches)) {
        $isSuite = (substr($matches[1], -1) == 's');
        if ($fileInfo->getPath() != $path && $isSuite) {
          echo "Adding Suite: " . $matches[1] . " in " . $this->name . "\n";
          $helper = TestSuiteHelper::create($matches[1], $fileInfo->getPath());
          $this->suite->addTest($helper->suite());
        } elseif ($fileInfo->getPath() == $path && !$isSuite) {
          require_once $fileInfo->getRealPath();
          echo "Adding Test: " . $matches[1] . " in " . $this->name . "\n";
          $this->suite->addTestSuite($matches[1]);
        }
      }
    }
  }
}
